home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
language
/
pcl_src.zoo
/
macros.lsp
< prev
next >
Wrap
Lisp/Scheme
|
1992-09-13
|
31KB
|
911 lines
;;;-*-Mode:LISP; Package:(PCL (LISP WALKER)); Base:10; Syntax:Common-lisp -*-
;;;
;;; *************************************************************************
;;; Copyright (c) 1985, 1986, 1987, 1988, 1989, 1990 Xerox Corporation.
;;; All rights reserved.
;;;
;;; Use and copying of this software and preparation of derivative works
;;; based upon this software are permitted. Any distribution of this
;;; software or derivative works must comply with all applicable United
;;; States export control laws.
;;;
;;; This software is made available AS IS, and Xerox Corporation makes no
;;; warranty about the software, its performance or its conformity to any
;;; specification.
;;;
;;; Any person obtaining a copy of this software is requested to send their
;;; name and post office or electronic mail address to:
;;; CommonLoops Coordinator
;;; Xerox PARC
;;; 3333 Coyote Hill Rd.
;;; Palo Alto, CA 94304
;;; (or send Arpanet mail to CommonLoops-Coordinator.pa@Xerox.arpa)
;;;
;;; Suggestions, comments and requests for improvements are also welcome.
;;; *************************************************************************
;;;
;;; Macros global variable definitions, and other random support stuff used
;;; by the rest of the system.
;;;
;;; For simplicity (not having to use eval-when a lot), this file must be
;;; loaded before it can be compiled.
;;;
(in-package 'pcl)
(proclaim '(declaration
#-Genera values ;I use this so that Zwei can remind
;me what values a function returns.
#-Genera arglist ;Tells me what the pretty arglist
;of something (which probably takes
;&rest args) is.
#-Genera indentation ;Tells ZWEI how to indent things
;like defclass.
class
variable-rebinding
pcl-fast-call
specializer-names
))
;;; Age old functions which CommonLisp cleaned-up away. They probably exist
;;; in other packages in all CommonLisp implementations, but I will leave it
;;; to the compiler to optimize into calls to them.
;;;
;;; Common Lisp BUG:
;;; Some Common Lisps define these in the Lisp package which causes
;;; all sorts of lossage. Common Lisp should explictly specify which
;;; symbols appear in the Lisp package.
;;;
(eval-when (compile load eval)
(defmacro memq (item list) `(member ,item ,list :test #'eq))
(defmacro assq (item list) `(assoc ,item ,list :test #'eq))
(defmacro rassq (item list) `(rassoc ,item ,list :test #'eq))
(defmacro delq (item list) `(delete ,item ,list :test #'eq))
(defmacro posq (item list) `(position ,item ,list :test #'eq))
(defmacro neq (x y) `(not (eq ,x ,y)))
(defun make-caxr (n form)
(declare (type fixnum n))
(if (< n 4)
`(,(nth n '(car cadr caddr cadddr)) ,form)
(make-caxr (the fixnum (- n 4)) `(cddddr ,form))))
(defun make-cdxr (n form)
(declare (type fixnum n))
(cond ((zerop n) form)
((< n 5) `(,(nth n '(identity cdr cddr cdddr cddddr)) ,form))
(t (make-cdxr (the fixnum (- n 4)) `(cddddr ,form)))))
)
(defun true (&rest ignore) (declare (ignore ignore)) t)
(defun false (&rest ignore) (declare (ignore ignore)) nil)
(defun zero (&rest ignore) (declare (ignore ignore)) 0)
(defvar *keyword-package* (find-package 'keyword))
(defun make-plist (keys vals)
(if (null vals)
()
(list* (car keys)
(car vals)
(make-plist (cdr keys) (cdr vals)))))
(defun remtail (list tail)
(if (eq list tail) () (cons (car list) (remtail (cdr list) tail))))
;;; ONCE-ONLY does the same thing as it does in zetalisp. I should have just
;;; lifted it from there but I am honest. Not only that but this one is
;;; written in Common Lisp. I feel a lot like bootstrapping, or maybe more
;;; like rebuilding Rome.
;;;
;;; Modified 5/8/92 to work right on THE forms and to not wrap an
;;; extra lambda if none of the variables are complex -- TL.
(defun un-the (form)
"Returns the actual form within a form that may start with THE."
(if (and (listp form) (eq (car form) 'the))
(un-the (third form))
form))
(defun simple-eval-access-p (form)
"Returns whether evaluation of the form is 'simple', i.e. does not
require computation to calculate. This is true of constants, variables,
and functions."
(or (constantp form) ;; Form is a constant?
(symbolp form) ;; Form is a variable?
(and (listp form)
(eq (car form) 'function)) ;; Form is a function?
(and (listp form) ;; If form starts with THE, the real form
(eq (car form) 'the) ;; third element.
(simple-eval-access-p (third form)))))
(defmacro once-only (vars &body body)
(let ((gensym-var (gensym))
(run-time-vars (gensym "RUN-TIME-VARS"))
(run-time-vals (gensym "RUN-TIME-VALS"))
(expand-time-val-forms ()))
(dolist (var vars)
(push `(if (simple-eval-access-p ,var)
,var
(let ((,gensym-var (gensym ,(symbol-name var))))
(push ,gensym-var ,run-time-vars)
(push ,var ,run-time-vals)
,gensym-var))
expand-time-val-forms))
`(let* (,run-time-vars
,run-time-vals
(wrapped-body
(let ,(mapcar #'list vars (reverse expand-time-val-forms))
,@body)))
(if ,run-time-vars
`(let ,(mapcar #'list (reverse ,run-time-vars)
(reverse ,run-time-vals))
,wrapped-body)
wrapped-body))))
(defun declaimed-p-name (name)
(if (consp name)
(get-internal-setf-function-name (cadr name))
name))
#-(or cmu) ; And probably others, but this is the only I know.
(unless (fboundp 'declaim)
(defmacro declaim (&rest decl-specs)
(let ((proclamations NIL))
(declare (list proclamations))
(dolist (decl-spec decl-specs)
#-(or cmu kcl)
(when (eq (car decl-spec) 'ftype)
(dolist (name (cddr decl-spec))
(setf (get (declaimed-p-name name) 'ftype-declaimed-p) T)))
(push `(proclaim ',decl-spec) proclamations))
(if (cdr proclamations)
`(progn ,@proclamations)
(car proclamations)))))
#-(or cmu kcl)
(defun function-ftype-declaimed-p (name)
"Returns whether the function given by name already has its ftype declaimed."
(get (declaimed-p-name name) 'ftype-declaimed-p))
(deftype index () `(integer 0 ,most-positive-fixnum))
(defmacro pop-key-value (key
settable-lambda-list
&optional
default-value)
;; If key is on the settable-lambda-list, then it and its value is
;; destructively removed from the list, and its value is returned.
;; Else, default-value is returned and the settable-lambda-list
;; stays the same.
(once-only (key)
`(let ((list-ptr ,settable-lambda-list))
(if (eq (car list-ptr) ,key)
(progn
(setf ,settable-lambda-list (cddr list-ptr))
(cadr list-ptr))
(progn
(setf list-ptr (cdr list-ptr))
(let ((next-cdr (cdr list-ptr)))
(loop (when (null next-cdr)
(return ,default-value))
(when (eq (car next-cdr) ,key)
(setf (cdr list-ptr) (cddr next-cdr))
(return (cadr next-cdr)))
(setf next-cdr
(cdr (setf list-ptr (cdr next-cdr)))))))))))
(defmacro copy-simple-vector (orig)
"Fast way to copy a simple-vector."
#-kcl
(once-only (orig)
`(let* ((i 0)
(n (length (the simple-vector ,orig)))
(new (make-array n)))
(declare (type index i n) (type simple-vector new))
(tagbody
begin-loop
(if (>= i n) (go end-loop))
(setf (svref new i) (svref (the simple-vector ,orig) i))
(setf i (the index (1+ i)))